package org.cvbpl;

public class Matrix {
	public final int height, width;
	private double[][] matrix;
	
	public Matrix(int height, int width) {
		this.height = height;
		this.width = width;
		matrix = new double[width][height];
	}
	
	public void set(int row, int col, double d) {
		matrix[row][col] = d;
	}
	
	public double get(int row, int col) {
		return matrix[row][col];
	}
	
	public Matrix convolve(Matrix mask) {
		Matrix result = new Matrix(this.height, this.width);
		
		final int maskCenterRow = mask.height / 2;
		final int maskCenterCol = mask.width / 2;
		
		for(int applyRow = 0; applyRow < this.height; applyRow++) {
			for(int applyCol = 0; applyCol < this.width; applyCol++) {
				int sum = 0;
				
				for(int maskRow = 0; maskRow < mask.height; maskRow++) {
					for(int maskCol = 0; maskCol < mask.width; maskCol++) {
						double imageValue = get_wrap(
								applyRow + maskRow - maskCenterRow,
								applyCol + maskCol - maskCenterCol);
						double maskValue = mask.get(maskRow, maskCol);
						sum += imageValue * maskValue;
					}
				}
				
				result.set(applyRow, applyCol, sum);
			}
		}
		
		return result;
	}
	
	private double get_wrap(int row, int col) {
		while(row < 0)
			row += height;
		while(col < 0)
			col += width;
		while(row >= width)
			row -= height;
		while(col >= height)
			col -= width;
		
		return get(row, col);
	}
}
